package com.wcbtest.webs;

import com.jcraft.jsch.*;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;

public class JSchUtils {

    /**
     * 使用JSch执行远程SSH命令的工具方法
     * @param host 远程主机IP或域名
     * @param port SSH端口，默认22
     * @param username 用户名
     * @param password 密码（如果使用密码认证）
     * @param privateKeyPath 私钥路径（如果使用密钥认证）
     * @param passphrase 私钥密码（如果有）
     * @param command 要执行的命令
     * @param timeout 连接超时时间（毫秒）
     * @return 包含执行结果的对象
     */
    public static SshResult executeSshCommand(
            String host, int port, String username,
            String password, String privateKeyPath, String passphrase,
            String command, int timeout) {

        Session session = null;
        Channel channel = null;
        InputStream inputStream = null;
        InputStream errorStream = null;

        try {

            long start = System.currentTimeMillis();
            // 创建JSch对象
            JSch jsch = new JSch();
            // 设置私钥（如果有）
            if (privateKeyPath != null && !privateKeyPath.isEmpty()) {
                if (passphrase != null) {
                    jsch.addIdentity(privateKeyPath, passphrase);
                } else {
                    jsch.addIdentity(privateKeyPath);
                }
            }
            // 创建SSH会话
            session = jsch.getSession(username, host, port);
            // 设置密码（如果使用密码认证）
            if (password != null) {
                session.setPassword(password);
            }
            // 配置SSH会话
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no"); // 测试环境使用，生产环境建议使用安全验证
            session.setConfig(config);
            // 设置超时并连接
            session.setTimeout(timeout);
            session.connect();
            System.out.println("连接耗时"+ (System.currentTimeMillis() - start));


            // 打开执行命令的通道
            channel = session.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);

            // 获取命令输出流
            channel.setInputStream(null);
            ((ChannelExec) channel).setErrStream(System.err);

            inputStream = channel.getInputStream();
            errorStream = ((ChannelExec) channel).getErrStream();

            // 连接通道
            channel.connect();

            // 读取标准输出
            String stdout = readStream(inputStream);
            // 读取错误输出
            String stderr = readStream(errorStream);

            // 等待命令执行完成并获取退出状态
            while (channel.isConnected()) {
                Thread.sleep(100);
            }
            int exitStatus = channel.getExitStatus();

            return new SshResult(exitStatus, stdout, stderr);

        } catch (JSchException | java.io.IOException | InterruptedException e) {
            System.err.println("执行SSH命令时发生异常: " + e.getMessage());
            return new SshResult(-1, null, "执行命令时发生异常: " + e.getMessage());
        } finally {
            // 关闭资源
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
            try {
                if (inputStream != null){ inputStream.close();};
                if (errorStream != null) {errorStream.close();};
            } catch (java.io.IOException e) {
                System.err.println("关闭流时发生异常: " + e.getMessage());
            }
        }
    }

        /**
         * 读取输入流内容
         */
    private static String readStream(InputStream inputStream) throws java.io.IOException {
        StringBuilder result = new StringBuilder();
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, StandardCharsets.UTF_8)
        );

        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line).append("\n");
        }

        return result.toString();
    }

    public static void main(String[] args) {
        // 示例：使用密码认证执行命令
        long start = System.currentTimeMillis();
        System.out.println("执行命令开始");
        SshResult result = executeSshCommand(
                "192.168.110.130",    // 服务器主机名或IP
                22,                    // SSH端口
                "root",       // 用户名
                "123456",       // 密码
                null,                  // 私钥路径（不使用）
                null,                  // 私钥密码（不使用）
                "ls -l",               // 要执行的命令
                30000                  // 超时时间（毫秒）
        );
        System.out.println("命令耗时"+ (System.currentTimeMillis() - start));

        if (result.isSuccess()) {
            System.out.println("命令执行成功：");
            System.out.println(result.getStdout());
        } else {
            System.err.println("命令执行失败，退出码：" + result.getExitStatus());
            System.err.println(result.getStderr());
        }
    }
    /**
     * SSH命令执行结果类
     */
    public static class SshResult {
        private final int exitStatus;
        private final String stdout;
        private final String stderr;

        public SshResult(int exitStatus, String stdout, String stderr) {
            this.exitStatus = exitStatus;
            this.stdout = stdout;
            this.stderr = stderr;
        }

        public int getExitStatus() { return exitStatus; }
        public String getStdout() { return stdout; }
        public String getStderr() { return stderr; }
        public boolean isSuccess() { return exitStatus == 0; }

        @Override
        public String toString() {
            return "Exit Status: " + exitStatus + "\n" +
                    "Standard Output:\n" + stdout + "\n" +
                    "Error Output:\n" + stderr;
        }
    }
}
